package com.binance.basedao.mybatis;

import com.binance.basedao.complexquery.CustomQueryParam;

import java.util.List;

/**
 * <b>Description:</b>〈用于业务service继承的常用查询服务类〉<br/>
 * @author hongchaoMao <br/>
 *         Create date: 2017/9/18
 * @version v1.0.0
 */
public interface BaseService<T> {

    /**
     * 查询表中所有记录
     * @return List结果集
     */
    List<T> getAll();

    /**
     * 根据参数对象属性值做'='查询(用在确定只返回一条记录的查询场景,如果数据库存在多条则会抛出异常)
     * @param findParams 查询参数对象,(Note:属性或者get方法上加了@Transient注解的,或者属性值为null的都将不做为查询条件)
     * @return 唯一记录
     */
    T getOne(T findParams);

    /**
     * 根据参数对象属性值做'='查询
     * @param findParams 查询的参数对象,(Note:属性或者get方法上加了@Transient注解的,或者属性值为null的都将不做为查询条件)
     * @return List结果集
     */
    List<T> getByObj(T findParams);

    /**
     * 根据参数对象属性值做'='查询,支持分页
     * @param findParams 查询的参数对象,(Note:属性或者get方法上加了@Transient注解的,或者属性值为null的都将不做为查询条件)
     * @param start 分页查询的开始偏移量
     * @param limit 分页查询的每页查询条数
     * @return List结果集
     */
    List<T> getByObj(T findParams, Integer start, Integer limit);

    /**
     * 根据参数对象属性值做'='查询,支持分页及自定义字段排序(其中Sort对象包含column和direction,分别表示表的列名和排序方式DESC/ASC)
     * @param findParams 查询的参数对象,(Note:属性或者get方法上加了@Transient注解的,或者属性值为null的都将不做为查询条件)
     * @param start 分页查询的开始偏移量
     * @param limit 分页查询的每页查询条数
     * @param sortList 指定的排序字段集(为null或empty则不指定排序列)
     * @return List结果集
     */
    List<T> getByObj(T findParams, Integer start, Integer limit, List<Sort> sortList);

    /**
     * 根据主键ID值查询一条记录(将按照Model类中添加@Id注解的属性,如果没有@Id注解则按照表的'id'列作为查询条件)
     * @param id 主键ID
     * @return 唯一记录
     */
    T getById(Long id);

    /**
     * 根据参数对象属性值做'='查询记录数
     * @param params 条件参数对象,(Note:属性或者get方法上加了@Transient注解的,或者属性值为null的都将不做为查询条件)
     * @return 记录数
     */
    int count(T params);

    /**
     * 根据参数对象属性值做'like'查询记录数(与count(T params)不同之处是条件操作符用'like',查询语句中的'%'占位符须在参数对象的属性值中设置)
     * @param findParams 条件参数对象,(Note:属性或者get方法上加了@Transient注解的,或者属性值为null的都将不做为查询条件)
     * @return 记录数
     */
    int countLike(T findParams);

    /**
     * 根据自定义条件语句列表组合查询记录数(用于一些相对复杂点的查询，比如'!=','in','not in'等)
     * @param customQueryParams 查询的条件集(主要包含WithValueQueryParam和NoValueQueryParam两种,具体参考类中属性)
     * @return 记录数
     */
    int countQuery(List<CustomQueryParam> customQueryParams);

    /**
     * 根据自定义条件语句列表组合查询结果列表(用于一些相对复杂点的查询，比如'!=','in','not in'等)
     * @param customQueryParams 查询的条件集(主要包含WithValueQueryParam和NoValueQueryParam两种,具体参考类中属性)
     * @return List结果集
     */
    List<T> query(List<CustomQueryParam> customQueryParams);

    /**
     * 根据自定义条件语句列表组合查询结果列表(用于一些相对复杂点的查询，比如'!=','in','not in'等),支持分页及排序
     * @param customQueryParams 查询的条件集(主要包含WithValueQueryParam和NoValueQueryParam两种,具体参考类中属性)
     * @param start 分页的偏移位置
     * @param limit 分页查询的记录数
     * @param sortList 指定的排序字段集(参数值为null或empty则不指定排序列),注意:Sort对象中的column属性的值是表的列名而不是Entity的属性名
     * @return List结果集
     */
    List<T> query(List<CustomQueryParam> customQueryParams, Integer start, Integer limit, List<Sort> sortList);

    /**
     * 根据参数对象属值性做'like'查询(语句中的'%'占位符由参数值自带),支持分页查询
     * @param findParams 查询的参数对象
     * @param start 分页查询的开始的偏移量
     * @param limit 分页查询的每页查询条数
     * @return 结果集
     */
    List<T> findByObj(T findParams, Integer start, Integer limit);

    /**
     * 根据参数对象属性做'like'查询(语句中的'%'占位符由参数值自带)
     * @param findParams 查询的参数对象,(Note:属性或者get方法上加了@Transient注解的,或者属性值为null的都将不做为查询条件)
     * @return 结果集
     */
    List<T> findByObj(T findParams);

    /**
     * 对象持久化操作
     * @param t 需要插入的Mode对象,(Note:属性或者get方法上加了@Transient注解的,或者属性值为null的都将不做为插入值)
     */
    void insert(T t) throws DataCommitException;

    /**
     * 对象持久化操作,如果违反唯一键约束的数据行将会忽略
     * @param t 插入的Model对象,(Note:属性或者get方法上加了@Transient注解的,或者属性值为null的都将不做为插入值)
     * @throws DataCommitException
     */
    void insertIgnore(T t) throws DataCommitException;

    /**
     * 将参数集合循环插入到表中
     * @param list 需要insert的model集
     * @throws DataCommitException
     */
    void insert(List<T> list) throws DataCommitException;

    /**
     * 批量将参数集合插入到表中,与insert(List<T> list)不同的是只产生一条SQL语句,推荐使用
     * @param list 需要insert的model集
     * @throws DataCommitException
     */
    void batchInsert(List<T> list) throws DataCommitException;

    /**
     * 批量将参数集合插入到表中,与insert(List<T> list)不同的是只产生一条SQL语句,如果有违反唯一键约束的数据行将会忽略
     * @param list 需要insert的model集
     * @throws DataCommitException
     */
    void batchInsertIgnore(List<T> list) throws DataCommitException;

    /**
     * 按照主键ID删除记录(将按照Model类中添加@Id注解的属性,如果没有@Id注解则按照表的'id'列作为查询条件)
     * @param id 主键ID字段
     * @throws DataCommitException
     */
    void deleteById(Long id) throws DataCommitException;

    /**
     * 循环遍历ID集合按照主键ID删除记录
     * @param ids 需要delete的model集(id属性需要包含值)
     * @throws DataCommitException
     */
    void deleteByIds(List<Long> ids) throws DataCommitException;

    /**
     * 按参数对象中添加了@Id注解的属性的字段进行删除
     * @param t 需要delete的model对象
     * @throws DataCommitException
     */
    void delete(T t) throws DataCommitException;

    /**
     * 按参数对象中添加了@Id注解的属性的字段进行删除
     * @param list 需要delete的model集
     * @throws DataCommitException
     */
    void delete(List<T> list) throws DataCommitException;

    /**
     * 更新Model对象(id字段不能为空,将其他字段修改成参数对象的值)，通常用在对查询出后的对象做update
     * @param t 要更新的持久化对象
     * @throws DataCommitException
     */
    void update(T t) throws DataCommitException;

    /**
     * 遍历调用update(T t)方法循环更新
     * @param list 需要更新的持久化对象集
     * @throws DataCommitException
     */
    void update(List<T> list) throws DataCommitException;

}
